#!/usr/bin/python
# -*- coding: utf-8 -*-

#################################################################
#                                                               
# 功能简述：通过读取网页信息，获取工行实时的纸黄金价格
#          
#     
# 传入参数: icbc_gold.py
#
# 摘    要：                                                                                                 
#                                             
# 人员身份      日期修改内容   
# －－－－－－－－－－－－
# zhougp    创建      20130513
#                        
#################################################################

import sys
import os
import ConfigParser
import urllib2
from HTMLParser import HTMLParser
import time  
import sqlite3

import socket
# 取网页时，让它不挂死
socket.setdefaulttimeout(15.0)

# 是否发送短信
send_sms_flag = False

INI_FILE = "./icbc_gold.ini"

def get_conf(search_section, search_option, default_str):
    """ 读取配置文件中的项 """
    try:
        for section in config.sections():
            if search_section == section:
                for option in config.options(section):
                    if search_option == option:
                        return config.get(section, option)    
    except:
        return default_str
    
    return default_str

def init_config():
    """ 初始化基本配置 """
    # 全局变量
    global base_url

    # 读取相关配置
    base_url = get_conf("SYS", "base_url", "")
    
class icbc_gold_sqlite_ope:
    def __init__(self, db_file):
        self.conn = sqlite3.connect(db_file)
    
    def create_icbc_gold_table(self):
        # 创建数据表
        sql_str = "CREATE TABLE tb_icbc_gold_history("
        sql_str = sql_str + "d_insert_date    timestamp,"
        sql_str = sql_str + "cur_price        float,"
        sql_str = sql_str + "max_price        float,"
        sql_str = sql_str + "min_price        float"
        sql_str = sql_str + ")"
        
        cu = self.conn.cursor()
        cu.execute(sql_str)
        self.conn.commit()
            
    def del_icbc_gold_table(self):
        # 删除数据表
        sql_str = "DROP TABLE tb_icbc_gold_history"
        cu = self.conn.cursor()
        cu.execute(sql_str)
        self.conn.commit()

    def del_icbc_gold_dat(self):
        # 删除数据
        sql_str = "delete from tb_icbc_gold_history "
        cu = self.conn.cursor()
        cu.execute(sql_str)
        self.conn.commit()
        
    def insert_icbc_gold_dat(self, cur_price, max_price, min_price):
        # 增加一期的数据
        # 首先删除这一期的数据，然后再增加
        cu = self.conn.cursor()
        
        sql_str = "INSERT INTO tb_icbc_gold_history(" \
                  "d_insert_date, cur_price, max_price, min_price)" \
                  "VALUES(CURRENT_TIMESTAMP, %f, %f, %f)" \
                  %(cur_price, max_price, min_price)
        cu.execute(sql_str)
        self.conn.commit()
    
    def close(self):
        # 连接退出
        self.conn.close()

class ICBCParser(HTMLParser):
    # return a dictionary mapping anchor texts to lists
    # of associated hyperlinks

    def __init__(self, verbose=0):
        self.find_flag = -1
        self.icbc_cur_price = 0.0
        self.icbc_max_price = 0.0
        self.icbc_min_price = 0.0
        HTMLParser.__init__(self)

    def handle_starttag(self,tag,attrs):
        if tag =='td':
            pass
            #for name,value in attrs:
            #    print name, '|',  value

    def handle_data(self,data):
        data = data.strip()
        if len(data) <= 0:
            return
        
        if data == "人民币账户黄金":
            self.find_flag = 0
            return
        
        if self.find_flag >= 0:
            self.find_flag += 1
        
        if self.find_flag > 5:
            self.find_flag = -1
        
        if self.find_flag == 1:
            self.icbc_cur_price = float(data)
        if self.find_flag == 4:
            self.icbc_max_price = float(data) - 0.4
        if self.find_flag == 5:
            self.icbc_min_price = float(data) - 0.4
    
    def get_cur_price(self):
        return self.icbc_cur_price

    def get_max_price(self):
        return self.icbc_max_price

    def get_min_price(self):
        return self.icbc_min_price

def logic_flow():
    pre_max_price = 0.0
    pre_min_price = 0.0

    icbc_db = icbc_gold_sqlite_ope("./icbc_gold_db.dat")
    # icbc_db.create_icbc_gold_table()
    
    while True:
        try:
            req = urllib2.Request(base_url)
            f = urllib2.urlopen(req)
            html_str =  f.read()   
            f.close()
    
            p = ICBCParser()
            p.feed(html_str)
            p.close()
         
            # print len(html_str)
            # print html_str
    
            now = time.localtime(time.time())
            print time.strftime("%Y-%m-%d %H:%M:%S", now), "cur_price:", p.get_cur_price(), "  max_price:", p.get_max_price(), "  min_price:", p.get_min_price()
            
            icbc_db.insert_icbc_gold_dat(p.get_cur_price(), p.get_max_price(), p.get_min_price())
            
            if send_sms_flag == True:
                sub = "纸黄金当前价格：%f"%(p.get_cur_price())
                content = "纸黄金今天最高价为：%f,最低价为：%f"%(p.get_max_price(), p.get_min_price())
                command_str = "python D:\\workspace\\sms_fetion\\src\\139.py %s %s"%(sub, content)
                os.system(command_str)
        except:
            now = time.localtime(time.time())
            print time.strftime("%Y-%m-%d %H:%M:%S", now), "deal except."
            time.sleep(15)
            continue
        
        if pre_max_price != 0.0 and pre_min_price != 0.0:
            if pre_max_price < p.get_max_price() or pre_min_price > p.get_min_price():
                pre_max_price = p.get_max_price()
                pre_min_price = p.get_min_price()
                time.sleep(60*1.5)
                continue

        pre_max_price = p.get_max_price()
        pre_min_price = p.get_min_price()
        time.sleep(60*5)
    

# 除了即时交易外，还有另外两种交易的方式
# 1.止盈法：设定一个高于现有价格的成交价格，当到了这个价格时，即成交
# 2.止损法：设定一个低于现有价格的成交价格，当到了这个价格时，即成交
#    止损法可以设定当前价格以下的一个价格，如现在价格271，那么设定270，当到了270时，即卖出，当价格在不断上升时，可以不断调整这个价格，当下降时，则不动。
#    可以根据1分钟平均线，当向下洞穿1分钟平均线时，则卖出。
#
#
# 通过这两种方式，又可以将资金分批操作。
""" 主函数 """
if __name__ == "__main__":
    ini_file = ""
    if sys.argv[1:]:
        ini_file = sys.argv[1]
    else:
        ini_file = INI_FILE
    
    """ 判断配置文件是否存在  """
    if os.access(ini_file, os.F_OK) != True:
        print "Error:No such ini file:%s"%ini_file
        sys.exit(1)
    
    """ 读取配置文件  """
    config = ConfigParser.ConfigParser()
    config.read(ini_file)
    
    init_config()
    
    logic_flow()
    